package com.yonyou.crm.sys.shiro.realms;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.yonyou.crm.sys.login.rmitf.ILoginRmService;
import com.yonyou.crm.sys.user.entity.UserVO;
import com.yonyou.iuap.auth.session.SessionManager;
import com.yonyou.iuap.auth.shiro.StatelessToken;
import com.yonyou.iuap.auth.token.ITokenProcessor;
import com.yonyou.iuap.auth.token.TokenFactory;
import com.yonyou.iuap.auth.token.TokenParameter;

public class StatelessRealm extends AuthorizingRealm {
	private static final Logger logger = LoggerFactory.getLogger(StatelessRealm.class);

	@Autowired
	TokenFactory tokenFactory;

	@Autowired
	private SessionManager sessionManager;
	@Autowired
	private ILoginRmService loginService;
	

	public boolean supports(AuthenticationToken token) {
		return token instanceof StatelessToken;
	}

	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		
		String uname = (String) principals.getPrimaryPrincipal();
		UserVO userVO = loginService.login(uname);
		
		//根据用户获取分配的角色 资源
		Set<String> roleCodeSet = new HashSet<String>();
		Set<String> resSet = new HashSet<String>();
		
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addRoles(roleCodeSet);
		info.addStringPermissions(resSet);
		
		return info;
	}

	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken atoken) throws AuthenticationException {
		StatelessToken token = (StatelessToken) atoken;
		TokenParameter tp = token.getTp();
		String uname = (String) token.getPrincipal();
		ITokenProcessor tokenProcessor = token.getTokenProcessor();
		//根据token中的信息重新生成tokenStr,用与校验用户是否登陆
		String tokenStr = tokenProcessor.generateToken(tp);
		if ((tokenStr == null) || (!this.sessionManager.validateOnlineSession(uname, tokenStr))) {
			logger.error("User [{}] authenticate fail in System, maybe session timeout!", uname);
			throw new AuthenticationException("User " + uname + " authenticate fail in System");
		}

		return new SimpleAuthenticationInfo(uname, tokenStr, getName());
	}
}